﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Data;
using Microsoft.SharePoint.Utilities;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI.HtmlControls;
using ICSharpCode.SharpZipLib.Zip;
using System.Collections;
using System.Xml;
using System.Text;
using SiteProjects.Classes;

/*
Developed By: Bhupender Bindra
Developed On: 29th Nov 2010
Description: The code provides the user to download active document libraries of the download library list in zip folder.
Modified By: Jyoti Seth
Modified On: 14th Jun 2011
Description: The code directly picks all the document library of the current site 
              instead of only active document libraries in the download library list.
*/

//namespace DownloadContentKit.Layouts.ArchiveDownload
namespace SiteProjects.Layouts.DownloadContent
 
{
    public partial class Download : LayoutsPageBase
    {
        int checkoutStatus = 0; //check in and check out status

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                string authorName;

                //create a object in memory stream
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    //create a object to zip file builder and call memory stream
                    using (ZipFileBuilder builder = new ZipFileBuilder(memoryStream))
                    {
                        using (SPSite site = new SPSite(SPContext.Current.Web.Url))
                        {
                            using (SPWeb web = site.OpenWeb())
                            {
                                web.AllowUnsafeUpdates = true;

                                //get the loginname on sharepoint site
                                string userID = web.CurrentUser.LoginName.ToString();
                                int countList;
                                for (countList = 0; countList < SPContext.Current.Web.Lists.Count; countList++)
                                {
                                    //it will check if the list base type is document library, then only do the download.
                                    if (web.Lists[countList].BaseType == SPBaseType.DocumentLibrary)
                                    {
                                        SPDocumentLibrary documentLibrary = (SPDocumentLibrary)web.Lists[countList];

                                        //get all the items in this document library
                                        foreach (SPListItem item in documentLibrary.Items)
                                        {
                                            //collect the file
                                            SPFile file = item.File;
                                            //get login name who create a file
                                            authorName = file.Author.LoginName;
                                            //condition check current user and file user if both same then add folder and file
                                            if (userID == authorName)
                                            {
                                                if (checkoutStatus == 0)
                                                {
                                                    //this function used to add folder and add file
                                                    if (item.IsFolder())
                                                    {
                                                        AddFolder(builder, item.Folder, documentLibrary.Title.ToString());
                                                    }
                                                    else
                                                    {
                                                        AddFile(builder, item.File, documentLibrary.Title.ToString());
                                                    }
                                                }
                                                else
                                                {
                                                    break;
                                                }
                                            }
                                        }
                                        if (checkoutStatus != 0)
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (checkoutStatus == 0)
                        {
                            builder.Finish();
                            //used threading to some delay to write the file in stream
                            System.Threading.Thread.Sleep(10000);
                            //call the write function
                            WriteStreamToResponse(memoryStream);
                        }
                        else
                        {

                            StringBuilder msgScript = new StringBuilder();
                            msgScript.Append("<script language='javascript'>");
                            msgScript.Append("alert('Please download the files later on. Currently one or more files are checked out by other users.');");
                            msgScript.Append("window.close();");
                            msgScript.Append("</script>");
                            Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "MyScript", msgScript.ToString());

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string errMessage=ex.Message;
                errMessage=errMessage.Replace("'","");
                StringBuilder errScript = new StringBuilder();
                errScript.Append("<script language='javascript'>");
                errScript.Append("alert('" + errMessage.ToString() + "');");
                errScript.Append("window.close();");
                errScript.Append("</script>");
                Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "MyScript", errScript.ToString());
            }
        }


        /// <summary>
        /// this function used to add file in zip builder and check file status
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="file"></param>
        /// <param name="folder"></param>
        public void AddFile(ZipFileBuilder builder, SPFile file, string folder)
        {
            try
            {
                if (file.CheckOutStatus != SPFile.SPCheckOutStatus.None)
                {
                    checkoutStatus = 1;
                }
                else
                {
                    using (Stream fileStream = file.OpenBinaryStream())
                    {
                        builder.Add(folder + "\\" + file.Name, fileStream);
                        fileStream.Close();
                    }
                }
            }
            catch
            {
            }
        }

        /// <summary>
        /// this function used to add folder and then file in zip builder
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="folder"></param>
        /// <param name="parentFolder"></param>
        public void AddFolder(ZipFileBuilder builder, SPFolder folder, string parentFolder)
        {
            string folderPath = parentFolder == string.Empty ? folder.Name : parentFolder + "\\" + folder.Name;
            builder.AddDirectory(folderPath);

            foreach (SPFile file in folder.Files)
            {
                AddFile(builder, file, folderPath);
            }

            foreach (SPFolder subFolder in folder.SubFolders)
            {
                AddFolder(builder, subFolder, folderPath);
            }
        }

        /// <summary>
        /// this function used to write the file in zip folder
        /// </summary>
        /// <param name="ms"></param>
        private void WriteStreamToResponse(MemoryStream ms)
        {
            if (ms.Length > 0)
            {
                string fileName = DateTime.Now.ToFileTime().ToString() + ".zip";
                Response.Clear();
                Response.ClearHeaders();
                Response.ClearContent();
                Response.AddHeader("Content-Length", ms.Length.ToString());
                Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
                Response.ContentType = "application/octet-stream";

                byte[] buffer = new byte[ms.Length];
                ms.Position = 0;
                int num;
                do
                {
                    num = ms.Read(buffer, 0, buffer.Length);
                    Response.OutputStream.Write(buffer, 0, num);
                }

                while (num > 0);
                Response.Flush();
                Response.Clear();
            }
        }
    }
}
